package org.light.generator;

import java.util.ArrayList;
import java.util.List;

import org.light.core.Writeable;
import org.light.domain.Domain;
import org.light.domain.Field;
import org.light.domain.Method;
import org.light.domain.Statement;
import org.light.domain.Type;
import org.light.exception.ValidateException;
import org.light.utils.FieldUtil;
import org.light.utils.WriteableUtil;

public class UtilMethodsGenerator {

	public static Method generateMaxIdMethod(Domain domain) throws ValidateException{
		Method method = new Method();
		method.setStandardName("maxId");
		method.setReturnType(new Type("Long"));
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,1,"Long max = 0L;"));
		sList.add(new Statement(2000L,1,"for ("+domain.getCapFirstDomainNameWithSuffix()+" "+domain.getLowerFirstDomainName()+": db){"));
		sList.add(new Statement(3000L,2,"if ("+domain.getLowerFirstDomainName()+".get"+domain.getDomainId().getCapFirstFieldName()+"() > max) {"));
		sList.add(new Statement(4000L,3,"max = "+domain.getLowerFirstDomainName()+".get"+domain.getDomainId().getCapFirstFieldName()+"();"));
		sList.add(new Statement(5000L,2,"}"));
		sList.add(new Statement(6000L,1,"}"));
		sList.add(new Statement(7000L,1,"return max;"));
		method.setMethodStatementList(WriteableUtil.merge(sList));
		return method;
	}

	public static Method generateInitDbMethod(Domain domain) throws ValidateException{
		Method method = new Method();
		method.setStandardName("initDb");
		method.setReturnType(new Type("List", domain, domain.getPackageToken()));
		method.setStatic(true);
		method.addAdditionalImport("java.text.SimpleDateFormat");
		method.addAdditionalImport("java.util.ArrayList");
		method.addAdditionalImport("java.util.List");
		List<Writeable> sList = new ArrayList<Writeable>();
		long serial = 1000L;
		sList.add(new Statement(serial+1000L,2,"SimpleDateFormat datetimeformater = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");"));
		sList.add(new Statement(serial+2000L,2,"SimpleDateFormat dateformater = new SimpleDateFormat(\"yyyy-MM-dd\");"));
		sList.add(new Statement(serial+3000L,2,"List<"+domain.getCapFirstDomainNameWithSuffix()+"> list = new ArrayList<>();"));
		sList.add(new Statement(serial+4000L,2,"try {"));
		serial += 5000L;		
		int dummySerial = 1;
		for (Domain d: domain.getDummyDb()) {
			sList.add(new Statement(serial,3,domain.getCapFirstDomainNameWithSuffix()+" "+domain.getLowerFirstDomainName()+ dummySerial+" = new "+domain.getCapFirstDomainNameWithSuffix()+"();"));
			serial += 1000L;
			for (Field f: d.getFields()) {
				sList.add(new Statement(serial,3,domain.getLowerFirstDomainName()+dummySerial+".set"+f.getCapFirstFieldName()+"("+FieldUtil.findTypeValueToken(f)+");"));
				serial += 1000L;
			}
			sList.add(new Statement(serial,3,"list.add("+domain.getLowerFirstDomainName()+dummySerial+");"));
			serial += 1000L;
			dummySerial ++;
		}
		sList.add(new Statement(serial,2,"} catch (Exception e){"));
		sList.add(new Statement(serial+1000L,2,"}"));
		sList.add(new Statement(serial+2000L,2,"return list;"));
		method.setMethodStatementList(WriteableUtil.merge(sList));
		return method;
	}
	
	public static Method generateInitOracleDbMethod(Domain domain) throws ValidateException{
		Method method = new Method();
		method.setStandardName("initDb");
		method.setReturnType(new Type("List", domain, domain.getPackageToken()));
		method.setStatic(true);
		method.addAdditionalImport("java.text.SimpleDateFormat");
		method.addAdditionalImport("java.util.ArrayList");
		method.addAdditionalImport("java.util.List");
		List<Writeable> sList = new ArrayList<Writeable>();
		long serial = 1000L;
		sList.add(new Statement(serial+1000L,2,"SimpleDateFormat datetimeformater = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");"));
		sList.add(new Statement(serial+2000L,2,"SimpleDateFormat dateformater = new SimpleDateFormat(\"yyyy-MM-dd\");"));
		sList.add(new Statement(serial+3000L,2,"List<"+domain.getCapFirstDomainNameWithSuffix()+"> list = new ArrayList<>();"));
		sList.add(new Statement(serial+4000L,2,"try {"));
		serial += 5000L;		
		int dummySerial = 1;
		for (Domain d: domain.getDummyDb()) {
			sList.add(new Statement(serial,3,domain.getCapFirstDomainNameWithSuffix()+" "+domain.getLowerFirstDomainName()+ dummySerial+" = new "+domain.getCapFirstDomainNameWithSuffix()+"();"));
			serial += 1000L;
			for (Field f: d.getFields()) {
				sList.add(new Statement(serial,3,domain.getLowerFirstDomainName()+dummySerial+".set"+f.getCapFirstFieldName()+"("+FieldUtil.findTypeValueOracleToken(f)+");"));
				serial += 1000L;
			}
			sList.add(new Statement(serial,3,"list.add("+domain.getLowerFirstDomainName()+dummySerial+");"));
			serial += 1000L;
			dummySerial ++;
		}
		sList.add(new Statement(serial,2,"} catch (Exception e){"));
		sList.add(new Statement(serial+1000L,2,"}"));
		sList.add(new Statement(serial+2000L,2,"return list;"));
		method.setMethodStatementList(WriteableUtil.merge(sList));
		return method;
	}
	
	public static Method generateDomainCloneMethod(Domain domain) throws ValidateException{
		Method method = new Method();
		method.setStandardName("clone");
		method.setReturnType(domain.getType());
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,1, domain.getCapFirstDomainNameWithSuffix()+" "+domain.getLowerFirstDomainName()+"0 = new "+domain.getCapFirstDomainNameWithSuffix()+"();"));
		long serial = 2000L;
		for (Field f : domain.getFields()) {
			sList.add(new Statement(serial,1, domain.getLowerFirstDomainName()+"0.set"+f.getCapFirstFieldName()+"(this.get"+f.getCapFirstFieldName()+"());"));
			serial += 1000L;
		}
		sList.add(new Statement(serial,1, "return " +domain.getLowerFirstDomainName()+"0;"));
		method.setMethodStatementList(WriteableUtil.merge(sList));
		return method;
	}
}
